#include "intersectionitem.h"

#include <QFont>
#include <QPen>
#include <QDebug>
#include <qmath.h>
#include "utilities.h"
#include "graphicsutilities.h"

IntersectionItem::IntersectionItem(QGraphicsItem *parent)
  : QGraphicsPathItem(parent)
{
  setZValue(GraphicsUtilities::LAYER_INTERSECTION);
  setBrush(Qt::darkGray);
  setPen(QPen(Qt::darkGray));
}

void IntersectionItem::addRoads(const StreetMap::RoadList &roads)
{
  foreach(StreetMap::Road* r, roads)
  {
    if (r->getFirstIntersection() && r->getSecondIntersection())
    {
      GeometryUtilities::LineSegment rLine;
      rLine.begin() = r->first();
      rLine.end() = r->second();
      if (r->getFirstIntersection()->name() == mName)
      {
        GeometryUtilities::LineSegment pLine(
          rLine.toPerpendicularFromBegin(0, r->width()));
        mLines.push_back(pLine);
        mPoints.push_back(pLine.begin());
        mPoints.push_back(pLine.end());
      }
      else
      {
        GeometryUtilities::LineSegment pLine(
          rLine.toPerpendicularFromEnd(0, r->width()));
        mLines.push_back(pLine);
        mPoints.push_back(pLine.begin());
        mPoints.push_back(pLine.end());
      }
    }
  }

  GeometryUtilities::Point center(0.0f,0.0f), dir(0.0f, -1.0f);
  foreach(GeometryUtilities::Point p, mPoints)
    center += p;
  center /= mPoints.count();

  for (int i=0; i<mPoints.count(); ++i)
  {
    for (int j=0; j<mPoints.count(); ++j)
    {
      GeometryUtilities::Point ip = mPoints.at(i),
                               jp = mPoints.at(j);
      ip -= center;
      ip.normalize();
      jp -= center;
      jp.normalize();
      qreal ia = GeometryUtilities::Point::signedangle(ip, dir) * 180.0/M_PI,
            ja = GeometryUtilities::Point::signedangle(jp, dir) * 180.0/M_PI;
      if (ia > 0) ia -= 360;
      if (ja > 0) ja -= 360;
      if (ia < ja)
      {
        GeometryUtilities::Point temp(mPoints.at(j));
        mPoints.replace(j, mPoints.at(i));
        mPoints.replace(i, temp);
      }
    }
  }

  createIntersection();
}

void IntersectionItem::setIntersectionName(const QString &name)
{
  mName = name;
  //createIntersection();
}

void IntersectionItem::setIntersectionCenter(const GeometryUtilities::Point &center)
{
  mCenter = center;
}

void IntersectionItem::createIntersection()
{
  if (mLines.count() > 1)
  {
    GeometryUtilities::Point center(0,0);
    foreach(GeometryUtilities::Point p, mPoints)
      center += p;
    center /= mPoints.count();

    // Fill the intersection in
    QPainterPath path;
    path.moveTo(mPoints.front().x(), mPoints.front().y());
    path.lineTo(mPoints.front().x(), mPoints.front().y());
    for(int i=1; i<mPoints.count(); ++i)
    {
      path.lineTo(mPoints.at(i).x(), mPoints.at(i).y());
    }
    path.closeSubpath();
    path.setFillRule(Qt::WindingFill);
    setPath(path);

    // Draw white lines at the end of each road.
    QPen whiteSolid(Qt::white);
    foreach(GeometryUtilities::LineSegment l, mLines)
    {
      QGraphicsLineItem* line(new QGraphicsLineItem(this));
      line->setPen(whiteSolid);
      line->setLine(l.toQLineF());
    }

    QGraphicsTextItem *n(new QGraphicsTextItem(mName, this));
    n->setDefaultTextColor(Qt::white);
    n->setPos(center.x()-7, center.y()-10);
  }
  else // label all intesections, not just ones with lines
  {
    QGraphicsTextItem *n(new QGraphicsTextItem(mName, this));
    n->setDefaultTextColor(Qt::white);
    n->setPos(mCenter.x()-8, mCenter.y()-10);
  }
}
